package Planificador.core.dispositivos;

import Planificador.core.algoritmos.AlgoritmoFIFO;
import Planificador.core.exceptions.ConsumioTodaLaRafagaCpuException;
import Planificador.core.exceptions.ConsumioTodaLaRafagaEntradaSalidaException;
import Planificador.core.exceptions.FinDeProcesoException;
import Planificador.core.proceso.Proceso;

public abstract class Dispositivo {

	protected Cola cola = new Cola(new AlgoritmoFIFO());
	protected Proceso procesoEnEjecucion;
	protected String nombre = "";

	public String getNombre(){
		return this.nombre;
	}
	
	public void cargarProcesoSiNecesita() {
		if (this.procesoEnEjecucion == null) {
			this.procesoEnEjecucion = this.cola.siguienteProceso();
			if (procesoEnEjecucion == null) {
				return;
			}

			this.entroProceso(procesoEnEjecucion);
		}
	}

	public void recibirQuantum() throws ConsumioTodaLaRafagaCpuException,
			FinDeProcesoException, ConsumioTodaLaRafagaEntradaSalidaException {
		this.cargarProcesoSiNecesita();

		if (procesoEnEjecucion == null) {
			return;
		}

		try {
			this.procesoEnEjecucion.recibirQuantum();
		} catch (FinDeProcesoException e) {
			throw new FinDeProcesoException();
		} catch (ConsumioTodaLaRafagaCpuException e) {
			throw new ConsumioTodaLaRafagaCpuException();
		} catch (ConsumioTodaLaRafagaEntradaSalidaException e) {
			throw new ConsumioTodaLaRafagaEntradaSalidaException();
		}

	}

	abstract void entroProceso(Proceso p);

	public void agregarProceso(Proceso p) {
		this.cola.addProceso(p);				
	}

	public Proceso sacarProcesoEnEjecucion() {
		Proceso p = this.procesoEnEjecucion;
		this.procesoEnEjecucion = null;
		return p;
	}

}
